package cn.agiledata.bank.linkbank.impl.cncb;

import java.math.BigDecimal;
import java.util.Date;

import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import cn.agiledata.bank.common.util.DateUtil;
import cn.agiledata.bank.linkbank.exception.LinkBankException;
import cn.agiledata.bank.linkbank.impl.AbstractBankNetPayRequest;
import cn.agiledata.bank.linkbank.impl.AbstractBankPayRequest;

/**
 * 中国中信银行网上银行支付请求
 * 
 * @author 马贤波
 * 
 */
public final class CncbNetPayRequest extends AbstractBankNetPayRequest {

	
    public CncbNetPayRequest() {
        super();
    }
 
    protected AbstractBankPayRequest getCopiedInstance() {
        return new CncbNetPayRequest();
    }

	public void setUserId(String userId) {	//商户操作员代码
		this.setParameter(CncbNetConstant.USER_ID, userId);
	}  
	
	public void setPswd(String pswd) {	//商户操作员登录密码
		this.setParameter(CncbNetConstant.PSWD, pswd);
	}
	
	public void setMerchantId(String merchantId) {	//商户号（15位，银行事先分配）
		this.setParameter(CncbNetConstant.SHOP_NO, merchantId);
	}	
	
	public void setDate(Date date) {	//定单日期（YYYYMMDD）
		String dateValue = DateUtil.date2String(date,
				CncbNetConstant.ORDER_DATE_FORMAT);
		this.setParameter(CncbNetConstant.ORDER_DATE, dateValue);
		String timeValue = DateUtil.date2String(date,
				CncbNetConstant.ORDER_TIME_FORMAT);
		this.setParameter(CncbNetConstant.ORDER_TIME, timeValue);		
	}
	
	public void setOrderId(String orderId) {	//定单号（商户提交）
		// TODO Auto-generated method stub
		this.setParameter(CncbNetConstant.ORDER_NO, orderId);
	}

    public void setAmount(BigDecimal amount) {	//交易金额
		// TODO Auto-generated method stub
		this.setParameter(CncbNetConstant.AMOUNT, amount.setScale(2).toString());
	}
    
	public void setRemark(String remark) {	//注释（可空）
		// TODO Auto-generated method stub
		this.setParameter(CncbNetConstant.MEMO, remark);
	}

	public void setMerchantUrl(String merchantUrl) {	//商户接收通知URL（<=100）
		// TODO Auto-generated method stub
		this.setParameter(CncbNetConstant.SHOP_URL, merchantUrl);
	}
	
	public String getMerchantUrl() {
		return getParameter(CncbNetConstant.SHOP_URL);
	}
	
    public String getCryptoKeyDescription() {
        return null;
    }
    /**
     * 
     */
	public void prepare() throws LinkBankException {
		setParameter(CncbNetConstant.SIGN_MSG, generatePayData());
	}
	
	private String generatePayData() {
		Document doc = DocumentHelper.createDocument();
		Element root = addRoot(doc);
		addOrderElement(root);
		String xml = doc.asXML();
		xml = xml.replaceFirst("encoding=\"[Uu][Tt][Ff]-8\"", "encoding=\"gb2312\"");
		xml = xml.replaceFirst("\r?\n", "");
		return xml;
	}
	
	private void addOrderElement(Element root) {
		String[] fieldNames = { CncbNetConstant.SHOP_URL,
								CncbNetConstant.USER_ID,
								CncbNetConstant.PSWD,
								CncbNetConstant.SHOP_NO,
								CncbNetConstant.ORDER_DATE,
								CncbNetConstant.ORDER_TIME,
								CncbNetConstant.ORDER_NO,
								CncbNetConstant.AMOUNT,
								CncbNetConstant.MEMO
		};
		addLeafTextElements(root, fieldNames);
	}
	
	private Element addRoot(Document doc) {
		Element root = doc.addElement(CncbNetConstant.ROOT);
		root.addAttribute(CncbNetConstant.TXCODE, CncbNetConstant.TXCODE_VALUE);
		return root;
	}
	
	private void addLeafTextElement(Element element, String fieldName) {
		element.addElement(fieldName).setText(getParameter(fieldName));
	}

	private void addLeafTextElements(Element element, String[] fieldNames) {
		for (int i = 0; i < fieldNames.length; i++) {
			addLeafTextElement(element, fieldNames[i]);
		}
	}
	
	protected String[] getValidKeys() {
		return new String[] { CncbNetConstant.SIGN_MSG };
	}





}
